/*
 * @(#)EnglishDocumentIndexFactory.java, 2024/2/18 17:38
 *
 * Copyright (c) 2018-2024, 四川蜀天梦图数据科技有限公司.
 * All rights reserved.
 */
package com.zhoufan.lucene;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType;
import org.apache.lucene.document.IntField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.similarities.BM25Similarity;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * EnglishDocumentIndexFactory
 *
 * @author fantazy
 * @version 1.0, 2024年02月18日
 */
public class EnglishDocumentIndexFactory
{
    Analyzer analyzer;

    static String INDEX_HOME = "f:/lucene/index";

    IndexWriter iw;

    @Before
    public void setup() throws IOException
    {
        Directory directory = FSDirectory.open(Paths.get(INDEX_HOME));
        analyzer = new StandardAnalyzer();
        IndexWriterConfig config = new IndexWriterConfig(analyzer);
        config.setSimilarity(new BM25Similarity());
        iw = new IndexWriter(directory, config);
    }

    @Test
    public void writeIntoLucene() throws URISyntaxException
    {
        final ClassLoader classLoader = EnglishDocumentIndexFactory.this.getClass().getClassLoader();
        if (null == classLoader)
        {
            System.exit(-1);
            throw new RuntimeException();
        }
        final URL uri = classLoader.getResource("document");
        try
        {
            Files.walkFileTree(Paths.get(uri.toURI()), new IndexCreatorFileVisitor(iw));
            iw.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    public static final class Article
    {
        private int no;

        private String title;

        private String content;

        private static final AtomicInteger noCounter = new AtomicInteger();

        public static Article cleanArticle(Path txt) throws IOException
        {
            String title = txt.getFileName().toString();
            int dotIndex = title.lastIndexOf(".");
            title = title.substring(0, dotIndex);
            System.out.println(title);

            String content = Files.lines(txt).collect(Collectors.joining()).toString();
            return new Article(noCounter.getAndIncrement(), title, content);
        }

        public Article(int no, String title, String content)
        {
            this.no = no;
            this.title = title;
            this.content = content;
        }
    }

    public static class IndexCreatorFileVisitor implements FileVisitor<Path>
    {

        private IndexWriter iw;

        public IndexCreatorFileVisitor(IndexWriter iw)
        {
            this.iw = iw;
        }

        @Override
        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException
        {
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException
        {
            System.out.println(file.getFileName());
            final Article article = Article.cleanArticle(file);
            writeArticle(article);
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException
        {
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException
        {
            return FileVisitResult.CONTINUE;
        }

        private void writeArticle(Article article) throws IOException
        {
            if (iw.isOpen())
            {
                Document document = new Document();
                document.add(new IntField("no", article.no, IntField.TYPE_STORED));
                document.add(new Field("title", article.title, TextField.TYPE_STORED));
                document.add(new Field("content", article.content, TextField.TYPE_STORED));
                iw.addDocument(document);
                iw.flush();
            }
        }
    }
}
